package data;

import java.util.ArrayList;

public class Location implements Comparable<Location>{
	
	private static final double CLUSTER_TRESHOLD = (0.1);

	private double latitude;
	
	private double longitude;
	
	private double elevation;
	
	public Location (final float latitude, final float longitude, final float elevation){
		this.latitude = latitude;
		this.longitude = longitude;
	}

	public Location (final float latitude, final float longitude){
		this.latitude = latitude;
		this.longitude = longitude;
	}

	public Location (final double latitude, final double longitude){
		this.latitude = latitude;
		this.longitude = longitude;
	}
	
	public Location (){
	}

	public void setLatitude(double d) {
		this.latitude = d;
	}

	public double getLatitude() {
		return latitude;
	}

	public void setLongitude(double sliceXFrom) {
		this.longitude = sliceXFrom;
	}

	public double getLongitude() {
		return longitude;
	}

	public void setElevation(double d) {
		this.elevation = d;
	}

	public double getElevation() {
		return elevation;
	}
	
	public int compareLL(Location o) {
		if (this.getCluster()>o.getCluster()){
			return 1;
		}
		else if (this.getCluster()<o.getCluster()){
			return -1;
		}
		else if (this.latitude>o.getLatitude()){
			return 1;
		}
		else if (this.latitude<o.getLatitude()){
			return -1;
		}
		else if (this.longitude>o.getLongitude()){
			return 1;
		}
		else if (this.longitude<o.getLongitude()){
			return -1;
		}
		return 0;
	}

	@Override
	public int compareTo(Location o) {
		if (compareLL(o) != 0){
			return compareLL(o);
		}
		else if (this.elevation>o.getElevation()){
			return 1;
		}
		else if (this.elevation<o.getElevation()){
			return -1;
		}
		return 0;
	}
	
	public int getCluster(){
		
		Integer cluster = (int) (Math.ceil(this.latitude)*361+Math.ceil(this.longitude)+180);
		
		return cluster;
		
	}

	public ArrayList<Integer> getNearClusters() {

		ArrayList<Integer> list = new ArrayList<Integer>(); 
		
		int cluster = this.getCluster();
		
		list.add(cluster);
		
		double modLat = this.latitude % 1;
		double modLong = this.longitude % 1;
		
		if (modLat < (0.1)){
			
			list.add(cluster-361);
			
			if (modLong < (0.1)){
				list.add(cluster-362);
			}
			else if (modLong > (0.9)){
				list.add(cluster-360);
			}

		}
		else if (modLat > (0.9)){
			list.add(cluster+361);			
			
			if (modLong < (0.1)){
				list.add(cluster+360);
			}
			else if (modLong > (0.9)){
				list.add(cluster+362);
			}
		}
		if (modLong < (0.1)){
			list.add(cluster-1);
		}
		else if (modLong > (0.9)){
			list.add(cluster+1);
		}
		
		return list;
	}
	
	public double getDistanceTo(Location to){
		double deltaLat = this.latitude - to.getLatitude();
		double deltaLong = this.longitude - to.getLongitude();
		double distance = Math.sqrt(deltaLat*deltaLat+deltaLong*deltaLong);
		return distance;
	}
	
	public String toString(){
		return this.getLatitude() + "|" + this.getLongitude();
	}
}
